package com.wx.rpc.service.handler;

import com.wx.rpc.service.request.RPCRequest;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.Socket;
import java.util.Map;

/**
 * @author wx
 * @Description:
 * @date 2019/3/8 000816:13
 */
public class ProcessorHandler implements Runnable{
    /**
     * socket
     */
    private Socket socket;

    /**
     * 服务接口名称对应的服务的map
     */
    private Map<String, Object> handlerMap;

    public ProcessorHandler(Socket socket, Map<String, Object> handlerMap) {
        this.socket = socket;
        this.handlerMap = handlerMap;
    }

    @Override
    public void run() {
        // 处理请求
        ObjectInputStream inputStream = null;
        try {
            // 服务端处理客户端请求代码======================
            inputStream = new ObjectInputStream(socket.getInputStream());
            RPCRequest request = (RPCRequest) inputStream.readObject();
            Object result = invoke(request);

            // 服务端返回执行结果到客户端代码========================
            ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
            //输出结果
            outputStream.writeObject(result);
            //清除写缓冲区
            outputStream.flush();
            //关闭写流
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != inputStream) {
                try {
                    //关闭输入流
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    /**
     * @description: 通过客户端请求执行对应的方法
     * @author: wx
     * @date: 2019/3/8 0008
     * @param request
     * @return: java.lang.Object
     */
    public Object invoke(RPCRequest request) {
        try {
            //请求参数
            Object[] parameters = request.getParameters();
            Class<?>[] types = null;
            if (parameters != null){
                types = new Class[parameters.length];
                for (int i = 0; i < parameters.length; i++) {
                    types[i] = parameters[i].getClass();
                }
            }

            String version = request.getVersion();
            String serviceName = request.getClassName();
            if (StringUtils.isBlank(serviceName)){
                return new Object();
            }
            if (StringUtils.isNotBlank(version)) {
                serviceName = serviceName + "-" + version;
            }
            Object service = handlerMap.get(serviceName);
            //获取方法
            Method method = service.getClass().getMethod(request.getMethodName(), types);
            //执行方法并返回结果
            return method.invoke(service, parameters);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new Object();
    }


}
